// ----------------------------------------------------------------
// EMBED OBJECT CLASS
// Public License
// Authors: astgtciv@overstream.net and Arodicus@frontenddeveloper.net
// Version 1.2 (7/23/2007)
//
// The EmbedObject class allows you to retrieve the ID
// of the Flash Plugin from the Browser.
// ----------------------------------------------------------------
 
package com.asorg.browser {
 
	import flash.external.ExternalInterface;
	import flash.system.Capabilities;
 
	public class EmbedObject {
		private static  var _singleton:EmbedObject;
		private static  var SET_CALLBACK_NAME:String = "asorg_setEmbedObjectProps";
 
		private var embedObjectProps:Object;
		private var attemptedPropsRetrieval:Boolean = false;
 
		public function EmbedObject() {
			initialize();
		}
 
		private static function testFunc(){}
		private function initialize() {
			// Issuing the following create a memory leak in IE:
			ExternalInterface.addCallback(SET_CALLBACK_NAME,  external_SetEmbedObjectProps);
		}
 
 
		static public function getSingleton():EmbedObject {
			if (_singleton==null) {
				_singleton = new EmbedObject();
			}
			return _singleton;
		}
 
 
		static public function get singleton():EmbedObject {
			return getSingleton();
		}
		/////////////////////////// Interface ////////////////////////////////
 
 
 
		/*
		* A shortcut function to getting the EmbedObject's id. 
		* Calling this function is equivalent to calling getEnumerableParam('id')
		*/
		static public function getId():String {
			return getEnumerableParam('id');
		}
 
 
 
		/*
		* Returns the value of an enumerable parameter "param" in the embed object in the page (<embed> or <object>).
		* This is a shortcut, calling this function is equivalent to calling getEnumerableEmbedObjectParams()[param].
		* To get a non-enumerable (but readable) parameter, use getParamViaExternal.
		*/
		static public function getEnumerableParam(param:String):String {
			return String(getEnumerableParams()[param]);
		}
 
 
		/*
		* Returns an object with all the enumerable params of the embed object - i.e., params which are enumerable in 
		* javascript's for(param in embedobj) loop. The code always tries to return param 'id' as part of the object, 
		* whether it is considered enumerable by the browser or not.
		* 
		* Knowledge of the id property in params allows execution of javascript from flash
		* via ExternalInterface that references this embedded object (using document.getElementById()).
		* 
		* If it is not possible to get EmbedObjectParams, this function returns undefined.
		*/
 
		static public function getEnumerableParams():Object {
 
			if (!singleton.embedObjectProps) {
				singleton._getEmbedObjectProps();
			}
			// null??? singleton.embedObjectProps)
			return singleton.embedObjectProps;
		}
 
 
		/*
		* This is a shortcut to getting a readable (!) EmbedObject param dynamically via ExternalInterface.
		*/
		static public function getParamViaExternal(param:String):Object {
			return Object(singleton.executeJS("return document.getElementById('" + getEnumerableParam('id') + "').getAttribute('" + param + "');"));
		}
		//////////////// Implementation /////////////////////////////////////////
		public function _getEmbedObjectProps():Object {
			if (!attemptedPropsRetrieval) {
				retrieveEmbedObjectProps();
				attemptedPropsRetrieval = true;
			}
			return embedObjectProps;
		}
		public function retrieveEmbedObjectProps() {
			retrieveEmbedObjectPropsForTagname('embed');
			if (!embedObjectProps) {
				retrieveEmbedObjectPropsForTagname('object');
			}
		}
		// this function executes id-retrieving javascript searching for a particular tag name
		// (it will be called for "object" and "embed")
		public function retrieveEmbedObjectPropsForTagname(tagName:String) {
			// We iterate though all the tags with tagName, if the SET_ID_CALLBACK_NAME method is supported,
			// we call it.
			// The js used in version 1.0:
			// var js:String =  "var elts = document.getElementsByTagName('"+tagName+"'); for (var i=0;i<elts.length;i++) {if(typeof elts[i]."+SET_CALLBACK_NAME+" != 'undefined') { if (!elts[i].id) {elts[i].id='asorgid_'+Math.floor(Math.random()*100000);} var props = {}; props.id = elts[i].id; for (var j in elts[i]) { if ((typeof elts[i][j] == 'string')||(typeof elts[i][j] == 'number')||(typeof elts[i][j] == 'boolean')) { props[j] = elts[i][j]; } } elts[i]."+SET_CALLBACK_NAME+"(props); }}";
			if (Capabilities.playerType == "PlugIn" ||Capabilities.playerType == "ActiveX"  ) {
				var js:String =  "var elts = document.getElementsByTagName('"+tagName+"'); for (var i=0;i<elts.length;i++) {if(typeof elts[i]."+SET_CALLBACK_NAME+" != 'undefined') { if (!elts[i].getAttribute('id')) {elts[i].setAttribute('id','asorgid_'+Math.floor(Math.random()*100000));} var props = {}; props.id = elts[i].getAttribute('id'); for (var x=0; x < elts[i].attributes.length; x++) { props[elts[i].attributes[x].nodeName] = elts[i].attributes[x].nodeValue;} elts[i]."+SET_CALLBACK_NAME+"(props); }}";
 
 
				singleton.executeJS(js);
			} else {
				singleton.external_SetEmbedObjectProps({});
			}
		}
		// Executes a chunk of javascript code and returns the result
		public function executeJS(js:String):Object {
			return ExternalInterface.call("function() {" + js + "}");
		}
 
		public function external_SetEmbedObjectProps(props:Object) {
			this.embedObjectProps = props;
		}
 
	}
}